<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件

/**
 * 创建随机的字符串(盐)
 * @param string $string
 * @param int $length
 * @return string
 */

use think\facade\Env;
use think\Db;


function msectime()
{
    list($msec, $sec) = explode(' ', microtime());
    $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);

    return $msectime;
}


function mt_salt($string = '', $length = 10)
{
    $salt = '';
    if (empty($string)) {
        $random_string = Env::get('password.salt', '1234567890ABCDEBGHIJKLMNOBQRSTUVWSTZ&^*(a)-=|]1@.5}{><');
    } else {
        $random_string = $string;
    }
    while (strlen($salt) < $length) {
        $mt_rand = mt_rand(0, strlen($random_string));
        $salt .= substr($random_string, $mt_rand, 1);
    }

    return $salt;
}

function substr_text($str, $start = 0, $length, $charset = "utf-8", $suffix = "")
{
    if (function_exists("mb_substr")) {
        return mb_substr($str, $start, $length, $charset) . $suffix;
    } elseif (function_exists('iconv_substr')) {
        return iconv_substr($str, $start, $length, $charset) . $suffix;
    }
    $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk']  = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5']  = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";

    preg_match_all($re[$charset], $str, $match);

    $slice = join("", array_slice($match[0], $start, $length));

    return $slice . $suffix;
}

/**
 * 可以统计中文字符串长度的函数
 * @param $str要计算长度的字符串
 * @param $type计算长度类型，0(默认)表示一个中文算一个字符，1表示一个中文算两个字符
 *
 */
function abslength($str)
{
    if (empty($str)) {
        return 0;
    }
    if (function_exists('mb_strlen')) {
        return mb_strlen($str, 'utf-8');
    } else {
        preg_match_all("/./u", $str, $ar);
        return count($ar[0]);
    }
}


/*
 * 判断是否为手机端
 */
function is_wap()
{
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
        return true;
    }
    //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset($_SERVER['HTTP_VIA'])) {
        //找不到为flase,否则为true
        return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
    }
    //判断手机发送的客户端标志,兼容性有待提高
    if (isset($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = array(
            'nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-',
            'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian',
            'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile'
        );
        // 从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
            return true;
        }
    }
    //协议法，因为有可能不准确，放到最后判断
    if (isset($_SERVER['HTTP_ACCEPT'])) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false)
            && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false ||
                (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') <
                    strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))
        ) {
            return true;
        }
    }
    return false;
}


function is_idCard($vStr)
{
    $vCity = array(
        '11', '12', '13', '14', '15', '21', '22',
        '23', '31', '32', '33', '34', '35', '36',
        '37', '41', '42', '43', '44', '45', '46',
        '50', '51', '52', '53', '54', '61', '62',
        '63', '64', '65', '71', '81', '82', '91'
    );
    if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $vStr)) return false;
    if (!in_array(substr($vStr, 0, 2), $vCity)) return false;
    $vStr = preg_replace('/[xX]$/i', 'a', $vStr);
    $vLength = strlen($vStr);
    if ($vLength == 18) {
        $vBirthday = substr($vStr, 6, 4) . '-' . substr($vStr, 10, 2) . '-' . substr($vStr, 12, 2);
    } else {
        $vBirthday = '19' . substr($vStr, 6, 2) . '-' . substr($vStr, 8, 2) . '-' . substr($vStr, 10, 2);
    }
    if (date('Y-m-d', strtotime($vBirthday)) != $vBirthday) return false;
    if ($vLength == 18) {
        $vSum = 0;
        for ($i = 17; $i >= 0; $i--) {
            $vSubStr = substr($vStr, 17 - $i, 1);
            $vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr, 11));
        }
        if ($vSum % 11 != 1) return false;
    }
    return true;
}

function unlink_file($src)
{
    $path = Env::get('ROOT_PATH') . 'public';
    $path = str_replace('\\', '/', $path);
    $src = $path . $src;
    if (file_exists($src)) {
        @unlink($src);
    }
}

function get_age_by_id_card($id)
{

    //过了这年的生日才算多了1周岁
    if (empty($id)) {
        return '';
    }
    $date = strtotime(substr($id, 6, 8));
    //获得出生年月日的时间戳
    $today = strtotime('today');
    //获得今日的时间戳 111cn.net
    $diff = floor(($today - $date) / 86400 / 365);
    //得到两个日期相差的大体年数

    //strtotime加上这个年数后得到那日的时间戳后与今日的时间戳相比
    $age = strtotime(substr($id, 6, 8) . ' +' . $diff . 'years') > $today ? ($diff + 1) : $diff;

    return $age;
}

/**
 * @param $birth
 * @return mixed
 */
function get_age($birth)
{
    list($birthYear, $birthMonth, $birthDay) = explode('-',  $birth);
    list($currentYear, $currentMonth, $currentDay) = explode('-', date('Y-m-d'));

    $age = $currentYear - $birthYear - 1;

    if ($currentMonth > $birthMonth || $currentMonth == $birthMonth && $currentDay >= $birthDay) {
        $age++;
    }

    return $age;
}

function is_https()
{
    if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
        return true;
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        return true;
    } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
        return true;
    }
    return false;
}

/**
 * 获取用户设备信息
 */
function get_device_info()
{
    $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    if (stristr($agent, 'iPad')) {
        $fb_fs = "iPad";
    } else if (preg_match('/Android (([0-9_.]{1,3})+)/i', $agent, $version)) {
        $fb_fs = "Android " . $version[1];
    } else if (stristr($agent, 'Linux')) {
        $fb_fs = "Linux";
    } else if (preg_match('/iPhone OS (([0-9_.]{1,3})+)/i', $agent, $version)) {
        $fb_fs = "iPhone " . $version[1];
    } else if (preg_match('/Mac OS X (([0-9_.]{1,5})+)/i', $agent, $version)) {
        $fb_fs = "OS X " . $version[1];
    } else if (preg_match('/unix/i', $agent)) {
        $fb_fs = "Unix";
    } else if (preg_match('/windows/i', $agent)) {
        $fb_fs = "Windows";
    } else {
        $fb_fs = "";
    }
    return $fb_fs;
}

function addLog($info = '', $level = 'info')
{
    trace($info, $level);
}

/**
 * POST 请求
 * @param string $url
 * @param array $param
 * @param boolean $post_file 是否文件上传
 * @return string content
 */
function http_post($url, $param, $post_file = false)
{
    $postUrl = $url;
    $curlPost = $param;
    $ch = curl_init(); //初始化curl
    curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页
    curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
    curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
    $data = curl_exec($ch); //运行curl
    curl_close($ch);
    return $data;
}

// 概率计算
function get_rand($proArr)
{
    $result = '';
    //概率数组的总概率精度
    $proSum = array_sum($proArr);
    //概率数组循环
    foreach ($proArr as $key => $proCur) {
        $randNum = mt_rand(1, $proSum);       //抽取随机数
        if ($randNum <= $proCur) {
            $result = $key;             //得出结果
            break;
        } else {
            $proSum -= $proCur;
        }
    }
    unset($proArr);
    return $result;
}

function get_sex($idcard)
{
    if (empty($idcard)) return null;
    $sexint = (int) substr($idcard, 16, 1);
    return $sexint % 2 === 0 ? 2 : 1;
}
if (!function_exists('getclientip')) {

    function getclientip($proxy_override = true)
    {
        //return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '-';
        if ($proxy_override) {
            /* 优先从代理那获取地址或者 HTTP_CLIENT_IP 没有值 */
            $ip = empty($_SERVER["HTTP_X_FORWARDED_FOR"]) ? (isset($_SERVER["HTTP_CLIENT_IP"]) ? $_SERVER["HTTP_CLIENT_IP"] : "") : $_SERVER["HTTP_X_FORWARDED_FOR"];
        } else {
            /* 取 HTTP_CLIENT_IP, 虽然这个值可以被伪造, 但被伪造之后 NS 会把客户端真实的 IP 附加在后面 已经没有NS了 不需要这段了 */
            //$ip = empty($_SERVER["HTTP_CLIENT_IP"]) ? NULL : $_SERVER["HTTP_CLIENT_IP"];
            $ip = $_SERVER['REMOTE_ADDR']??"";
        }
        /* 真实的IP在以逗号分隔的最后一个, 当然如果没用代理, 没伪造IP, 就没有逗号分离的IP 无NS 无逗号 已没用了 */
        if ($p = strrpos($ip, ",")) {
            $ip = trim(substr($ip, $p + 1)); //坑爹有空格
        }
        if (empty($ip)) {
            $ip = $_SERVER['REMOTE_ADDR']??"";
        }
        return trim($ip);
    }
}
function response_api_loanshop($errno = 0, $msg = '', $data = [], $type = 'json', $is_exit = true)
{
    logToTmp('logout', $errno);
    if ($type == 'json') {
        header('Content-Type:application/json; charset=utf-8');
    }
    if ($is_exit) {
        if (!$data) {
            $data = [];
        }
        exit(json_encode(["code" => $errno, "data" => $data, "message" => $msg], JSON_UNESCAPED_UNICODE));
    }
}

if (!function_exists("logToTmp")) {

    function logToTmp($fileName, $content, $isAutoWrap = true)
    {
        $fileName = substr(strtolower(preg_replace("/[^a-zA-Z0-9_.]/i", "", $fileName)), 0, 128);
        if ($fileName == '') {
            $fileName = 'default.log';
        }
        // var_dump(php_sapi_name());exit;
        if (php_sapi_name() == 'cli') {
            $fileName .= '_cli';
        }
        $content = readArray($content);
        $filePath = '/tmp/' . $fileName . '.' . date("Ymd");
        $isAutoWrap && $content .= "\n";
        $handle = fopen($filePath, 'a');
        list($usec, $sec) = explode(" ", microtime());
        $msec = round($usec * 1000);
        $now = "[" . date("Y-m-d H:i:s") . "." . $msec . "]" . getclientip() . '|'; //直接添加时间
        fwrite($handle, $now . $content);
        fclose($handle);
    }
}
if (!function_exists("readArray")) {

    function readArray($data)
    {
        $str = "";
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                if (is_array($value)) {
                    $str .= $key . "={" . readArray($value) . "},";
                } else {
                    $str .= $key . "=" . $value . ",";
                }
            }
        } else {
            $str = $data;
        }
        return $str;
    }
}
// 随意花返回结果
function response_api_Suiyihua($errno = 0, $msg = '', $data = [], $type = 'json', $is_exit = true)
{
    logToTmp('suiyihua', $errno);
    if ($type == 'json') {
        header('Content-Type:application/json; charset=utf-8');
    }
    if ($is_exit) {
        exit(json_encode(["code" => $errno, "data" => $data, "message" => $msg], JSON_UNESCAPED_UNICODE));
    }
}
// 融客汇返回结果
function response_api_Rongkehui($errno = 0, $msg = '', $data = [], $type = 'json', $is_exit = true)
{
    logToTmp('rongkehui', $errno);
    if ($type == 'json') {
        header('Content-Type:application/json; charset=utf-8');
    }
    if ($is_exit) {
        exit(json_encode(["Code" => $errno, "data" => $data, "Msg" => $msg], JSON_UNESCAPED_UNICODE));
    }
}
function response_api_Lvxin($errno = 0, $msg = '', $data = [], $type = 'json', $is_exit = true)
{
    logToTmp('lvxin', $errno);
    if ($type == 'json') {
        header('Content-Type:application/json; charset=utf-8');
    }
    if ($is_exit) {
        exit(json_encode(["dealStatus" => $errno, "data" => $data, "dealDesc" => $msg], JSON_UNESCAPED_UNICODE));
    }
}
function juheYzmcurl($params, $ispost = 0)
{
    $params = http_build_query($params);
    $url = 'http://v.juhe.cn/sms/send'; //短信接口的URL
    $httpInfo = array();
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22');
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    if ($ispost) {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_URL, $url);
    } else {
        if ($params) {
            curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
        } else {
            curl_setopt($ch, CURLOPT_URL, $url);
        }
    }
    $response = curl_exec($ch);
    if ($response === FALSE) {
        //echo "cURL Error: " . curl_error($ch);
        return false;
    }
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
    curl_close($ch);
    logToTmp("juhe", $params);
    logToTmp("juhe", $response);
    $response = json_decode($response, true);
    if ($response['error_code'] == 0) {
        return true;
    }
    return false;
}
if (!function_exists('curl_http')) {

    /**
     * curl操作
     * @param string $url 请求地址
     * @param string $method 请求类型
     * @param string $postfields 请求参数
     * @param string $headers 头信息
     * @param string $debug 调试模式
     * @return string
     */
    function curl_http($url, $method = 'get', $postfields = null, $headers = array(), $debug = false)
    {
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ci, CURLOPT_TIMEOUT, 30);
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ci, CURLOPT_USERAGENT, 'agent');

        switch ($method) {
            case 'POST':
                curl_setopt($ci, CURLOPT_POST, true);
                if (!empty($postfields)) {
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
                }
                break;
        }
        curl_setopt($ci, CURLOPT_URL, $url);
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);

        $response = curl_exec($ci);
        //$http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);

        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);

            echo '=====info=====' . "\r\n";
            print_r(curl_getinfo($ci));

            echo '=====$response=====' . "\r\n";
            print_r($response);
        }
        curl_close($ci);
        return $response;
    }
}
function lixiaoyunLogin($mobile = '', $pass = '')
{
    $param['device'] = 'open_api';
    $param['login'] = $mobile;
    $param['password'] = $pass;
    $url = 'https://lxcrm.weiwenjia.com/api/v2/auth/login';
    $rst = curl_http($url, "POST", $param);
    logToTmp("lixiaoyun", $param);
    logToTmp("lixiaoyun", $rst);
    return $rst;
}
function AesDecriypt128($string, $key, $encri_type = 'AES-128-ECB')
{
    $decrypted = openssl_decrypt(base64_decode($string), $encri_type, $key, OPENSSL_RAW_DATA);
    return $decrypted;
}
function strToHex($string)
{
    $hex = "";
    $tmp = "";
    for ($i = 0; $i < strlen($string); $i++) {
        $tmp = dechex(ord($string[$i]));
        $hex .= strlen($tmp) == 1 ? "0" . $tmp : $tmp;
    }
    $hex = strtoupper($hex);
    return $hex;
}
function rsaEncrypt($rawData, $pubKey)
{ //合作方公钥
    // $pubKey = file_get_contents($publicKeyFile);
    $res = openssl_get_publickey($pubKey);
    if ($res == false) {
        throw new Exception('invalid public key'.$pubKey);
    }
    $keyInfo = openssl_pkey_get_details($res);
    $step = $keyInfo['bits'] / 8 - 11;
    $encryptedList = array();
    for ($i = 0, $len = strlen($rawData); $i < $len; $i += $step) {
        $data = substr($rawData, $i, $step);
        $encrypted = '';
        openssl_public_encrypt($data, $encrypted, $res);
        $encryptedList[] = ($encrypted);
    }
    openssl_free_key($res);
    $data = join('', $encryptedList);
    return $data;
}

function AespkcsPadding($data, $key) {
    $encoding = mb_detect_encoding($data, mb_detect_order(), false);
//        var_dump($data,$encoding);
//        $data = iconv($this->charset_gbk, $this->charset_utf8 . '//IGNORE', $data);
    $data= pkcsPadding($data, 8);
    $sign = openssl_encrypt($data, 'AES-128-ECB', $key,3);
    $return_str = base64_encode($sign);
//        var_dump($data,$return_str);exit;
    return $return_str;
}

function pkcsPadding($str, $blocksize) {
    $pad = $blocksize - (strlen($str) % $blocksize);
    return $str . str_repeat(chr($pad), $pad);
}
function getEcSign($timeStamp, $appId, $appSecret)
{
    $sign = "appId={$appId}&appSecret={$appSecret}&timeStamp={$timeStamp}";
    return strtoupper(md5($sign));
}